/*
 * Licensed to the 南京汇海交通科技有限公司
 *
 * Copyright (c) 2025.
 * All rights reserved.
 *
 * 本软件属南京汇海交通科技有限公司所有，在未获得南京汇海交通科技有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.cje.basic.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chframework.boot.core.response.result.ApiResult;
import com.chframework.boot.core.response.status.ApiStatusEnum;
import com.chframework.common.exception.ServiceException;
import com.chframework.common.thread.wrapper.BenchmarksFuture;
import com.cje.basic.base.BaseService;
import com.cje.basic.converter.DictDataBOConverter;
import com.cje.basic.converter.DictDataDOConverter;
import com.cje.basic.converter.DictTypeBOConverter;
import com.cje.basic.converter.DictTypeDOConverter;
import com.cje.basic.dataobject.DictDataDO;
import com.cje.basic.dataobject.DictTypeDO;
import com.cje.basic.pojo.bo.DictDataBO;
import com.cje.basic.pojo.bo.DictTypeBO;
import com.cje.basic.pojo.dto.DictDataPageDTO;
import com.cje.basic.pojo.dto.DictTypeDTO;
import com.cje.basic.pojo.dto.DictTypePageDTO;
import com.cje.basic.service.DictService;
import com.github.pagehelper.PageParam;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Slf4j
@Service
@Controller
@RequiredArgsConstructor
@RequestMapping("/service/basic")
public class DictServiceImpl extends BaseService implements DictService {

    @Override
    public ApiResult<IPage<DictTypeBO>> pageDictType(DictTypePageDTO dictTypePageDTO) {
        DictTypeDO dictTypeDO = DictTypeDOConverter.INSTANCE.convert(dictTypePageDTO.getDictTypeBO());
        return super.dictTypeDAO.pageDictType(dictTypeDO, dictTypePageDTO.getPageNum(), dictTypePageDTO.getPageSize())
                .thenApplyAsync(pageDictType -> {
                    IPage<DictTypeBO> pageDictTypeBO = DictTypeBOConverter.INSTANCE.convert(pageDictType);
                    return ApiResult.<IPage<DictTypeBO>>build()
                            .setStatus(ApiStatusEnum.SUCCESS)
                            .setResult(pageDictTypeBO);
                }).exceptionally(throwable -> {
                    throw new ServiceException(throwable.getCause());
                }).join();
    }

    @Override
    public ApiResult<PageInfo<DictDataBO>> pageDictData(DictDataPageDTO dictDataPageDTO) {
        PageParam pageParam = new PageParam(dictDataPageDTO.getPageNum(), dictDataPageDTO.getPageSize());
        DictDataDO dictDataDO = DictDataDOConverter.INSTANCE.convert(dictDataPageDTO.getDictData());

        return super.dictDataDAO.pageDictData(pageParam, dictDataDO)
                .thenApplyAsync(pageDictData -> {
                    PageInfo<DictDataBO> pageDictDataBO = DictDataBOConverter.INSTANCE.convert(pageDictData);
                    return ApiResult.<PageInfo<DictDataBO>>build()
                            .setStatus(ApiStatusEnum.SUCCESS)
                            .setResult(pageDictDataBO);
                }).exceptionally(throwable -> {
                    throw new ServiceException(throwable.getCause());
                }).join();
    }

    @Override
    public ApiResult<DictTypeBO> getDictType(DictTypeBO dictTypeBO) {
        DictTypeDO param = DictTypeDOConverter.INSTANCE.convert(dictTypeBO);

        // 异步操作：查询指定的字典类型
        BenchmarksFuture<DictTypeDO> dictTypeDOFuture = super.dictTypeDAO.getDictType(param);

        // 异步操作：查询指定字典类型的字典数据列表
        BenchmarksFuture<List<DictDataDO>> listDictDataDOFuture = dictDataDAO.listDictData(param.getDictType());

        // 异步操作：合并异步结果
        return dictTypeDOFuture.thenCombine(listDictDataDOFuture, (dictTypeDO, listDictDataDO) -> {
                    dictTypeDO.setDictDataList(listDictDataDO);
                    return dictTypeDO;
                })
                .thenApplyAsync(dictTypeDO -> ApiResult.<DictTypeBO>build()
                        .setStatus(ApiStatusEnum.SUCCESS)
                        .setResult(DictTypeBOConverter.INSTANCE.convert(dictTypeDO))
                )
                .exceptionally(throwable -> {
                    throw new ServiceException(throwable.getCause());
                }).join();
    }

    @Override
    public ApiResult<Boolean> postDictData(DictTypeDTO dictTypeDTO) {
        DictTypeDO dictTypeDO = DictTypeDOConverter.INSTANCE.convert(dictTypeDTO.getDictType());

        // 异步操作：保存字典类型
        BenchmarksFuture<Boolean> postDictTypeFuture = super.dictTypeDAO.postDictType(dictTypeDO);

        // 异步操作：保存字典类型关联的字典数据列表
        BenchmarksFuture<Boolean> postDictDataBatchFuture = dictDataDAO.postDictDataBatch(dictTypeDO.getDictDataList());

        // 异步操作：合并异步结果
        return postDictTypeFuture.thenCombine(postDictDataBatchFuture, (postDictTypeFlag, postDictDataBatchFlag) ->
                        postDictTypeFlag && postDictDataBatchFlag)
                .exceptionally(throwable -> {
                    throw new ServiceException(throwable.getCause());
                }).thenApplyAsync(resultFlag ->
                        ApiResult.<Boolean>build()
                                .setStatus(ApiStatusEnum.SUCCESS)
                                .setResult(resultFlag)
                ).join();
    }

    @Override
    public ApiResult<Boolean> deleteDictType(DictTypeDTO dictTypeDTO) {
        DictTypeDO dictTypeDO = DictTypeDOConverter.INSTANCE.convert(dictTypeDTO.getDictType());

        // 异步操作：删除指定的字典类型
        BenchmarksFuture<Boolean> deletedDictTypeFuture = super.dictTypeDAO.deleteDictType(dictTypeDO);

        // 异步操作：删除指定字典类型关联的字典数据列表
        BenchmarksFuture<Boolean> deleteDictDataFuture = super.dictDataDAO.deleteDictData(dictTypeDO.getDictType());

        // 异步操作：合并异步结果
        return deletedDictTypeFuture.thenCombine(deleteDictDataFuture, (deletedDictTypeFlag, deleteDictDataFlag) ->
                deletedDictTypeFlag && deleteDictDataFlag
        ).thenApplyAsync(resultFlag ->
                ApiResult.<Boolean>build()
                        .setStatus(ApiStatusEnum.SUCCESS)
                        .setResult(resultFlag)
        ).exceptionally(throwable -> {
            throw new ServiceException(throwable.getCause());
        }).join();
    }

    @Override
    public ApiResult<Boolean> putDictType(DictTypeBO dictTypeBO) {
        return super.dictTypeDAO.putDictType(DictTypeDOConverter.INSTANCE.convert(dictTypeBO))
                .thenApplyAsync(resultFlag ->
                        ApiResult.<Boolean>build()
                                .setStatus(ApiStatusEnum.SUCCESS)
                                .setResult(resultFlag)
                ).exceptionally(throwable -> {
                    throw new ServiceException(throwable.getCause());
                }).join();
    }

    @Override
    public ApiResult<Boolean> putDictData(DictDataBO dictDataBO) {
        return super.dictDataDAO.putDictData(DictDataDOConverter.INSTANCE.convert(dictDataBO))
                .thenApplyAsync(resultFlag ->
                        ApiResult.<Boolean>build()
                                .setStatus(ApiStatusEnum.SUCCESS)
                                .setResult(resultFlag)
                ).exceptionally(throwable -> {
                    throw new ServiceException(throwable.getCause());
                }).join();
    }

}
